package com.geek.gkpush.biz.jms;

import com.geek.gkpush.biz.event.order.FoodOrderEventMsgHandler;
import com.geek.gkpush.biz.jms.model.RecvFoodOrderModel;
import com.geek.gkpush.framework.event.EventMsgDispatch;
import com.geek.gkpush.framework.event.model.EventMsgInsertModel;
import com.geek.gkpush.framework.mq.AbstractMessageListenerConcurrently;
import com.geek.gkpush.util.enums.mq.MqEnum;
import com.geek.gkpush.util.json.JacksonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <h1>接收美食订单状态变化的消息监听器。</h1><br/>
 *
 * <h1><br/><a href="https://u.geekbang.org/subject/arch3/100614201">Java 业务架构实战营：https://u.geekbang.org/subject/arch3/100614201</a></h1><br/><h1><a href="https://gitee.com/ylimhhmily/BizArchPracticeCamp">Java 业务架构实战营代码地址：https://gitee.com/ylimhhmily/BizArchPracticeCamp</a></h1><br/><h1><a href="https://u.geekbang.org/subject/java4th/1001148?source=app_share">高级 Java 工程体系课 2023 版：https://u.geekbang.org/subject/java4th/1001148?source=app_share</a></h1><br/><h1><a href="https://time.geekbang.org/column/intro/100312101?tab=catalog">Dubbo 源码剖析与实战：https://time.geekbang.org/column/intro/100312101?tab=catalog</a></h1>
 *
 * @author hmilyylimh
 *         ^_^
 * @version 0.0.1
 *         ^_^
 * @date 2023/10/2
 *
 */
@Slf4j
@Component
public class RecvFoodOrderMqListener extends AbstractMessageListenerConcurrently<RecvFoodOrderModel> {

    @Autowired
    private EventMsgDispatch eventMsgDispatch;

    @Override
    public String getTopicName() {
        return MqEnum.Q_GKPUSH_RECV_FOOD_ORDER_TOPIC.getCode();
    }

    @Override
    protected void doConsumeMessage(List<RecvFoodOrderModel> msgList) {
        // 1. 抽取 msgList 中的订单号列表
        List<String> orderIdList = extractOrderIdList(msgList);

        // 2. 调用远程拉取最新数据
        List<Object> remoteList = fetchLatestFromRemote(orderIdList);

        // 3. 更新本地 db 数据
        updateLocalOrderList(remoteList);

        // 4. 推送数据至远程企业
        pushOrderList2Ent(remoteList);
    }

    @Override
    protected boolean onException(List<RecvFoodOrderModel> msgList) {
        // 构建事件消息模型列表
        List<EventMsgInsertModel> reqInsertList = buildEventMsgInsertModelList(msgList);

        // 转移给到事件消息功能模块
        eventMsgDispatch.batchInsertEventMsg(reqInsertList);

        // 只要不报错的话，那就返回成功了
        return true;
    }

    private List<EventMsgInsertModel> buildEventMsgInsertModelList(List<RecvFoodOrderModel> msgList) {
        // 循环遍历得到事件消息模型列表
        return msgList.stream()
                .map(item -> EventMsgInsertModel.create(
                            JacksonUtils.toJson(item),
                            FoodOrderEventMsgHandler.class,
                            item.getOrderId()))
                .collect(Collectors.toList());
    }

    private void pushOrderList2Ent(List<Object> remoteList) {
        // TODO 这里不做处理了，将数据组装，推送给到远程，也是一个纯业务代码逻辑
    }

    private void updateLocalOrderList(List<Object> remoteList) {
        // TODO 这里不做处理了，更新本地 db 就是个纯业务代码逻辑
    }

    private List<Object> fetchLatestFromRemote(List<String> orderIdList) {
        // TODO 这里就不写发送远程的代码了，假装从远程拿到了数据
        return null;
    }

    private List<String> extractOrderIdList(List<RecvFoodOrderModel> msgList) {
        return msgList.stream()
                .map(RecvFoodOrderModel::getOrderId)
                .collect(Collectors.toList());
    }
}